﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using University.Workshop.Model;
using University.Workshop.DataAccess;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Collections;

namespace University.Workshop.Business
{
    public static class CompareProductsManager
    {
        private static float CurrencyExchange = GetCurrencyExchange();
        public static Collection<ComparedProduct> GatherInformation(Collection<long> productIds)
        {
            if (productIds != null)
            {
                Collection<ComparedProduct> comparedProducts = new Collection<ComparedProduct>();
                foreach (long cProductId in productIds)
                {
                    ComparedProduct cProduct = new ComparedProduct();
                    cProduct.RelatedProduct = ProductDataAccess.GetProductById(cProductId);
                    User user = UserDataAccess.GetUserById(cProduct.RelatedProduct.SellerId);
                    cProduct.Seller = user.ContactInformation.Email;
                    cProduct.CurrentCity = user.ContactInformation.Department + " (" + user.ContactInformation.City + ")";
                    Auction auction = new Auction();
                    auction = AuctionDataAccess.GetAuctionByproductId(cProductId);
                    cProduct.Rate = RatingDataAccess.GetProductRatingsAverage(cProductId).ToString(CultureInfo.CurrentCulture);
                    if (auction != null)
                    {
                        cProduct.LastBidDate = auction.LastBidDate.ToShortDateString();
                        cProduct.LastBidPrice = auction.LastBidPrice.ToString(CultureInfo.CurrentCulture);
                        cProduct.BidCurrency = auction.Currency;
                        cProduct.AuctionExpirationDate = auction.Date.ToShortDateString();
                        User bidder = (UserDataAccess.GetUserById(auction.BidderUserId));
                        if(bidder != null)
                            cProduct.LastBidder = bidder.ContactInformation.Email;
                    }
                    else
                    {
                        cProduct.LastBidDate = "-";
                        cProduct.LastBidPrice = "-";
                        cProduct.BidCurrency = "";
                        cProduct.AuctionExpirationDate = "-";
                        cProduct.LastBidder = "-";
                    }
                    comparedProducts.Add(cProduct);
                }
                return comparedProducts;
            }
            return null;
        }

        private static Collection<ComparedProduct> Reverse(Collection<ComparedProduct> compProducts)
        {
            Collection<ComparedProduct> reversedList = new Collection<ComparedProduct>();
            for (int i = compProducts.Count - 1; i >= 0; i--)
            {
                reversedList.Add(compProducts[i]);
            }
            return reversedList;
        }

        private static Collection<ComparedProduct> SortByNewlyListed(Collection<ComparedProduct> compProducts)
        {
            var sortedList = (from cProduct in compProducts
                              orderby cProduct.RelatedProduct.Postdate
                              select cProduct).ToList();
            Collection<ComparedProduct> sortedCollection = new Collection<ComparedProduct>();
            foreach (var cProduct in sortedList)
            {
                sortedCollection.Add(cProduct);
            }
            return sortedCollection;
        }


        private static float GetCurrencyExchange()
        {
            try
            {
                Uri uri = new Uri("http://www.lostiempos.com/");
                HttpWebRequest webRequestObject = (HttpWebRequest)HttpWebRequest.Create(uri);
                WebResponse response = webRequestObject.GetResponse();
                Stream webStream = response.GetResponseStream();
                StreamReader reader = new StreamReader(webStream, Encoding.Default, true);
                String pageContent = reader.ReadToEnd();
                reader.Close();
                response.Close();
                var indice = pageContent.LastIndexOf("Venta: $us", System.StringComparison.Ordinal);
                pageContent = pageContent.Substring(indice + 34, 4);
                return float.Parse(pageContent, CultureInfo.GetCultureInfo("en-US"));
            }
            catch (WebException)
            {
                return -1;
            }
            catch (ArgumentOutOfRangeException)
            {
                return -1;
            }
            catch (FormatException)
            {
                return -1;
            }
        }

        public static float BSToDollars(float bolivianPrice)
        {
            float result;
            result = bolivianPrice / CurrencyExchange;
            return result;
        }

        public static float DollarsToBS(float dollars)
        {
            float result;
            result = dollars * CurrencyExchange;
            return result;
        }

        private static Collection<ComparedProduct> SortByLowestPrice(Collection<ComparedProduct> compProducts)
        {
            double convertionFactor = CurrencyExchange;
            if (convertionFactor == -1)
                convertionFactor = 6.91;
            foreach (var product in compProducts)
            {
                if (product.RelatedProduct.Currency == "Dollars")
                    product.RelatedProduct.Price = product.RelatedProduct.Price*(float) convertionFactor;
            }
            var sortedList = (from cProduct in compProducts
                              orderby cProduct.RelatedProduct.Price
                              select cProduct).ToList();
            Collection<ComparedProduct> sortedCollection = new Collection<ComparedProduct>();
            foreach (var cProduct in sortedList)
            {
                sortedCollection.Add(cProduct);
            }
            foreach (var product in sortedCollection)
            {
                if (product.RelatedProduct.Currency == "Dollars")
                    product.RelatedProduct.Price = product.RelatedProduct.Price / (float)convertionFactor;
            }
            return sortedCollection;
        }

        private static Collection<ComparedProduct> SortBySellerFromAToZ(Collection<ComparedProduct> compProducts)
        {
            var sortedList = (from cProduct in compProducts
                              orderby cProduct.Seller
                              select cProduct).ToList();
            Collection<ComparedProduct> sortedCollection = new Collection<ComparedProduct>();
            foreach (var cProduct in sortedList)
            {
                sortedCollection.Add(cProduct);
            }
            return sortedCollection;
        }

        public static Collection<ComparedProduct> SortBy(Collection<ComparedProduct> compProducts, int sortType)
        {
            switch (sortType)
            {
                case 2:
                    return SortByNewlyListed(compProducts);
                case 3:
                    return Reverse(SortByNewlyListed(compProducts));
                case 4:
                    return SortByLowestPrice(compProducts);
                case 5:
                    return Reverse(SortByLowestPrice(compProducts));
                case 6:
                    return SortBySellerFromAToZ(compProducts);
                case 7:
                    return Reverse(SortBySellerFromAToZ(compProducts));
                default:
                    return compProducts;
            }
        }

        public static Collection<long> DeleteProduct(Collection<long> prodIds, long prodId)
        {
            if (prodIds != null)
            {
                for (int i = 0; i < prodIds.Count; i++)
                {
                    if (prodId == prodIds[i])
                    {
                        prodIds.RemoveAt(i);
                    }
                }
            }
            return prodIds;
        }

        public static Collection<long> GetIdsList(Collection<ComparedProduct> compProducts)
        {
            Collection<long> idsList = new Collection<long>();
            if (compProducts != null)
            {
                foreach (var cProduct in compProducts)
                {
                    idsList.Add(cProduct.RelatedProduct.ProductId);
                }
            }
            return idsList;
        }
    }
}
